github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/util/print map recursive.go (about) 1 package util 2 3 import "fmt" 4 import "bytes" 5 6 // this does not work generically: 7 var Map_example_expl_1 map[float64]map[int]float64 8 9 // this is generic - but unnecessary: 10 var Map_example_expl_2 map[interface{}]map[interface{}]interface{} 11 12 var Map_example_right map[interface{}]interface{} 13 14 func init() { 15 16 Map_example_expl_1 = map[float64]map[int]float64{ 17 10: map[int]float64{0: 0, 1: 2}, 18 7.5: map[int]float64{0: 0, 1: 1.5}, 19 5.0: map[int]float64{0: 0, 1: 1}, 20 } 21 22 Map_example_expl_2 = map[interface{}]map[interface{}]interface{}{ 23 10: map[interface{}]interface{}{0: 0, 1: 2}, 24 7.5: map[interface{}]interface{}{0: 0, 1: 1.5}, 25 } 26 27 Map_example_right = map[interface{}]interface{}{ 28 "scalar_k1": "scalar_val", 29 "scalar_k2": 0.11111, 30 "key to invalidly typed submap =>": map[interface{}]float64{"xx": 0.111, 1: 0.5}, 31 "lvl 1 submap": map[interface{}]interface{}{0: 0, 1: 2}, 32 32168: map[interface{}]interface{}{"any type": 0, 1: "anywhere"}, 33 "lvl 2 submaps": map[interface{}]interface{}{ 34 "l1a": map[interface{}]interface{}{"l2a": 0, 1: 0.5}, 35 "l1b": map[interface{}]interface{}{0: 0, 1: 0.5}, 36 13: "mixing in a scalar", 37 }, 38 } 39 40 } 41 42 // PrintMap does print a map without recursion 43 func PrintMap(m map[interface{}]interface{}) string { 44 return PrintMapRecursive(m, 0) 45 } 46 47 // PrintMap prints a map - recursing through submaps 48 // concrete types, like map[float64]map[int]float64 49 // would have to be converted element by element 50 // to map[interface{}]interface{} 51 // the json.indent function might be similar 52 // but I did not bring it to work 53 func PrintMapRecursive(m1 map[interface{}]interface{}, depth int) string { 54 b1 := new(bytes.Buffer) 55 fiveSpaces := " " // html spaces 56 cxIndent := fmt.Sprint(depth * 40) 57 depthStyle := "" 58 if depth == 0 { 59 depthStyle = "margin-top:8px; border-top: 1px solid #aaa;" 60 } else { 61 darkening := 16 - 2*depth 62 bgc := fmt.Sprintf("%x%x%x", darkening, darkening, darkening) 63 depthStyle = "margin:0;padding:0;background-color:#" + bgc + ";" 64 } 65 for k1, m2 := range m1 { 66 b1.WriteString("<div style='" + depthStyle + "margin-left:" + cxIndent + "px;'>\n") 67 b1.WriteString(fmt.Sprint(k1)) 68 //b1.WriteString( "<br>\n" ) 69 switch typedvar := m2.(type) { 70 default: 71 type_unknown := fmt.Sprintf("<br>\n --this type switch does not support type %#v", typedvar) 72 //panic(type_unknown) 73 b1.WriteString(fiveSpaces + fmt.Sprintf("%#v", typedvar) + type_unknown) 74 case string: 75 b1.WriteString(fiveSpaces + typedvar) 76 case int, float64: 77 b1.WriteString(fiveSpaces + fmt.Sprint(typedvar)) 78 case nil: 79 b1.WriteString("nil interface") 80 case map[interface{}]interface{}: 81 b1.WriteString(PrintMapRecursive(typedvar, depth+1)) 82 } 83 b1.WriteString("<br>\n") 84 b1.WriteString("</div>\n") 85 } 86 return b1.String() 87 } 88 89 /* 90 func Test_print_map(t *testing.T){ 91 92 c, err := aetest.NewContext(nil) 93 if err != nil { 94 t.Errorf("could not get a context") 95 } 96 97 s := PrintMap(Map_example_right) 98 c.Infof("testing print map recursive ...") 99 if Test_want != s { 100 c.Errorf("want %s - got %s", Test_want, s ) 101 } 102 } 103 */ 104 105 const Test_want = `<div style='margin-top:8px; border-top: 1px solid #aaa;margin-left:0px;'> 106 scalar_k1 scalar_val<br> 107 </div> 108 <div style='margin-top:8px; border-top: 1px solid #aaa;margin-left:0px;'> 109 scalar_k2 0.11111<br> 110 </div> 111 <div style='margin-top:8px; border-top: 1px solid #aaa;margin-left:0px;'> 112 key to invalidly typed submap => map[interface {}]float64{"xx":0.111, 1:0.5}<br> 113 --this type switch does not support type map[interface {}]float64{"xx":0.111, 1:0.5}<br> 114 </div> 115 <div style='margin-top:8px; border-top: 1px solid #aaa;margin-left:0px;'> 116 lvl 1 submap<div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'> 117 0 0<br> 118 </div> 119 <div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'> 120 1 2<br> 121 </div> 122 <br> 123 </div> 124 <div style='margin-top:8px; border-top: 1px solid #aaa;margin-left:0px;'> 125 32168<div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'> 126 any type 0<br> 127 </div> 128 <div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'> 129 1 anywhere<br> 130 </div> 131 <br> 132 </div> 133 <div style='margin-top:8px; border-top: 1px solid #aaa;margin-left:0px;'> 134 lvl 2 submaps<div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'> 135 l1a<div style='margin:0;padding:0;background-color:#ccc;margin-left:80px;'> 136 l2a 0<br> 137 </div> 138 <div style='margin:0;padding:0;background-color:#ccc;margin-left:80px;'> 139 1 0.5<br> 140 </div> 141 <br> 142 </div> 143 <div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'> 144 l1b<div style='margin:0;padding:0;background-color:#ccc;margin-left:80px;'> 145 0 0<br> 146 </div> 147 <div style='margin:0;padding:0;background-color:#ccc;margin-left:80px;'> 148 1 0.5<br> 149 </div> 150 <br> 151 </div> 152 <div style='margin:0;padding:0;background-color:#eee;margin-left:40px;'> 153 13 mixing in a scalar<br> 154 </div> 155 <br> 156 </div> 157 `